﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "Snapsetdialog.h"
#include "ui_Snapsetdialog.h"
#include "UiCommonDialog.h"
#include "IPickPointAction.h"
#include "GmStyleSheetHelper.h"
#include "ISnapContext.h"
#include "ISnapSettings.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"
using namespace gcmp;


SnapSetDialog::SnapSetDialog(QWidget *parent) :
QDialog(parent, Qt::FramelessWindowHint),
    ui(NEW_AS_OWNER_PTR(Ui::SnapSetDialog))
{
    ui->setupUi(this);

    // 重设字体以合规
    QFont font = qApp->font();
    setFont(font);

    std::wstring styleSheetStr = GmStyleSheetHelper::Instance()->GetStyleData(L"new_gbmp");
    setStyleSheet(QString::fromStdWString(styleSheetStr));
    ui->gbmp_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    ui->gbmp_title->setIconVisible(false);
    ui->gbmp_title->setMaxButtonVisible(false);
    ui->gbmp_title->setMinButtonVisible(false);
    ui->gbmp_title->setText(QString::fromStdWString(GBMP_TR(L"捕捉设置")));
    this->setProperty("use_gbmp_title", true);
    connect(ui->pushButton_Ok, SIGNAL(clicked()), this, SLOT(OKButtonPushed()));
    connect(ui->pushButton_Cancel, SIGNAL(clicked()), this, SLOT(CancelButtonPushed()));
    connect(ui->pushButton_selAll, SIGNAL(clicked()), this, SLOT(SelectAllButtonPushed()));
    connect(ui->pushButton_deselall, SIGNAL(clicked()), this, SLOT(DeselecAllButtonPushed()));
    connect(ui->pushButton_AnnoDefault, SIGNAL(clicked()), this, SLOT(SetDefaultAngleAndLengthValue()));
    connect(ui->checkBox_closesnap, SIGNAL(clicked()), this, SLOT(SetIsEnableSnap()));
    connect(ui->checkBox_Length, SIGNAL(clicked()), this, SLOT(SetIsLengthSnap()));
    connect(ui->checkBox_Degree, SIGNAL(clicked()), this, SLOT(SetIsAngleSnap()));

    connect(ui->gbmp_title, &GmTitleBar::closeRequested, this, &SnapSetDialog::reject);
    connect(ui->gbmp_title, &GmTitleBar::moveRequested, this, &SnapSetDialog::onMoveRequested);

    InitDialog();
}

void SnapSetDialog::SetIsAngleSnap()
{
    bool isChecked = ui->checkBox_Degree->isChecked();
    ui->lineEdit_Degree->setEnabled(isChecked);

}

void SnapSetDialog::SetIsLengthSnap()
{
    bool isChecked = ui->checkBox_Length->isChecked();
    ui->lineEdit_Length->setEnabled(isChecked);

}

void SnapSetDialog::SetIsEnableSnap()
{
    bool isSnapEnabled = ui->checkBox_closesnap->isChecked();
    SetAllButtonStatus(!isSnapEnabled);
}

void SnapSetDialog::SetAllButtonStatus(bool inputStatus)
{
    ui->checkBox_end->setEnabled(inputStatus);
    ui->checkBox_centerpoint->setEnabled(inputStatus);
    ui->checkBox_online->setEnabled(inputStatus);
    ui->checkBox_horver->setEnabled(inputStatus);
    ui->checkBox_intersectpoint->setEnabled(inputStatus);
    ui->checkBox_perpecular->setEnabled(inputStatus); 
    ui->checkBox_Degree->setEnabled(inputStatus); 
    ui->lineEdit_snapDistance->setEnabled(inputStatus);
    ui->lineEdit_Degree->setEnabled(inputStatus);
    ui->pushButton_selAll->setEnabled(inputStatus);
    ui->pushButton_deselall->setEnabled(inputStatus);

    ui->checkBox_tange->setEnabled(inputStatus);
    ui->checkBox_center->setEnabled(inputStatus);

    ui->checkBox_quadrant->setEnabled(inputStatus);

    ui->checkBox_Length->setEnabled(inputStatus);
    ui->lineEdit_Length->setEnabled(inputStatus);
}

void SnapSetDialog::SetDefaultAngleAndLengthValue()
{
    ISnapSettings::GetGlobalSnapSettings()->InitSnapSettings();
    InitDialog();
}

void SnapSetDialog::SetGlobalAngleAndLength()
{
    std::vector<double> angleValues = ISnapSettings::GetGlobalSnapSettings()->GetSnapAngles();
    SetAngleValue(angleValues);
    std::vector<double> lengthValues = ISnapSettings::GetGlobalSnapSettings()->GetSnapLengths();
    SetLengthValue(lengthValues);
}

void SnapSetDialog::SetAngleValue(std::vector<double>& angleValue)
{
    QString angleString;
    QString splitStr = " ; ";

    FOR_EACH(curVale, angleValue)
    {
        QString curString = QString::number(curVale) + splitStr;
        angleString += curString;
    }
    int splitLength = splitStr.length();
    angleString = angleString.left(angleString.length() - splitLength);
    ui->lineEdit_Degree->setText(angleString);
}

void SnapSetDialog::SetLengthValue(std::vector<double>& lengthValue)
{
    QString splitStr = " ; ";
    int splitLength = splitStr.length();
    QString lengthString;
    FOR_EACH(curVale, lengthValue)
    {
        QString curString = QString::number(curVale) + splitStr;
        lengthString += curString;
    }
    lengthString = lengthString.left(lengthString.length() - splitLength);

    ui->lineEdit_Length->setText(lengthString);
}

void SnapSetDialog::SelectAllButtonPushed()
{
    SetAllStatus(true);
    ISnapSettings* curSet = ISnapSettings::GetGlobalSnapSettings();
    DBG_WARN_AND_RETURN_VOID_UNLESS(curSet, L"获取全局捕捉设置失败",L"GDMPLab",L"2024-03-30");
    curSet->SetCanSnapCustomPoint(true);
}

void SnapSetDialog::DeselecAllButtonPushed()
{
    SetAllStatus(false);
    ISnapSettings* curSet = ISnapSettings::GetGlobalSnapSettings();
    DBG_WARN_AND_RETURN_VOID_UNLESS(curSet, L"获取全局捕捉设置失败",L"GDMPLab",L"2024-03-30");
    curSet->SetCanSnapCustomPoint(false);
}

void SnapSetDialog::SetAllStatus(bool inputStatus)
{
    ui->checkBox_end->setChecked(inputStatus);
    ui->checkBox_centerpoint->setChecked(inputStatus);
    ui->checkBox_online->setChecked(inputStatus);
    ui->checkBox_horver->setChecked(inputStatus);
    ui->checkBox_intersectpoint->setChecked(inputStatus);
    ui->checkBox_perpecular->setChecked(inputStatus);
    ui->checkBox_tange->setChecked(inputStatus);
    ui->checkBox_center->setChecked(inputStatus);
    ui->checkBox_quadrant->setChecked(inputStatus);
}

void SnapSetDialog::InitDialog()
{

    bool isSnapEnabled                = false;
    bool isEndSnapEnabled             = false;
    bool isMiddleSnapEnabled          = false;
    bool isOnLineSnapEnabled          = false;
    bool isHorVerSnapEnabled          = false;
    bool isDirectionSnapEnabled       = false;
    bool isGridSnapEnabled            = false;
    bool isPerpecularSnapEnabled      = false;
    bool isIntersecOnLineSnapEnabled  = false;
    bool isIntersecSnapEnabled        = false;
    bool isAligmentSnapEnabled        = false;
    bool isQuadrantSnapEnabled      = false;

    bool isCenterSnapEnabled          = false;
    bool isTangentSnapEnabled         = false;

    bool isRemoteParallel = false;
    bool isRemotePerpendicular = false;
    bool isRemoteExtension = false;

    bool isOnlyOnWPSnapEnabled        = false;
    double roundDisantce              = false;
    double distanceSnapSize;

    bool isSnapLength                 = false;
    bool isSnapAngle                  = false;

    ISnapSettings* curSet = ISnapSettings::GetGlobalSnapSettings();
    isSnapEnabled =               !curSet->IsSnapOff();
    // 对象捕捉
    isEndSnapEnabled =             curSet->CanSnapEndPoint();
    isMiddleSnapEnabled =          curSet->CanSnapMiddlePoint();
    isOnLineSnapEnabled =          curSet->CanSnapNearest();
    isHorVerSnapEnabled =          curSet->CanSnapHorizontalVerticalLine();
    isPerpecularSnapEnabled =      curSet->CanSnapPerpendicularPoint();
    isIntersecOnLineSnapEnabled =  curSet->CanSnapIntersectionPoint();
    isIntersecSnapEnabled =        curSet->CanSnapIntersectionPoint();
    isQuadrantSnapEnabled =        curSet->CanSnapQuadrants();

    isCenterSnapEnabled   =        curSet->CanSnapCenter();
    isTangentSnapEnabled   =       curSet->CanSnapTangent();

    // 远程捕捉
    //-----------------------------------------------------------------------------------
    isRemoteParallel = curSet->CanSnapParallel();
    isRemotePerpendicular = curSet->CanSnapPerpendicular();
    isRemoteExtension = curSet->CanSnapExtension();

    distanceSnapSize =             curSet->GetSnapDistance();

    isSnapLength                =  curSet->CanSnapLength();
    isSnapAngle                 =  curSet->CanSnapAngle();
    //圆心和切线Enable
    ui->checkBox_tange->setEnabled(true);
    ui->checkBox_center->setEnabled(true);

    ui->checkBox_Length->setEnabled(true);
    ui->checkBox_Degree->setEnabled(true);

    ui->checkBox_closesnap->setChecked(!isSnapEnabled);
    ui->checkBox_end->setChecked(isEndSnapEnabled);
    ui->checkBox_centerpoint->setChecked(isMiddleSnapEnabled);
    ui->checkBox_online->setChecked(isOnLineSnapEnabled);
    ui->checkBox_horver->setChecked(isHorVerSnapEnabled);
    ui->checkBox_perpecular->setChecked(isPerpecularSnapEnabled);
    ui->checkBox_intersectpoint->setChecked(isIntersecSnapEnabled);
    ui->checkBox_quadrant->setChecked(isQuadrantSnapEnabled);

    ui->checkBox_center->setChecked(isCenterSnapEnabled);
    ui->checkBox_tange->setChecked(isTangentSnapEnabled);

    //------------------------------------------------------------------------------
    ui->checkBox_remoteParallel->setChecked(isRemoteParallel);
    ui->checkBox_remotePerpendicular->setChecked(isRemotePerpendicular);
    ui->checkBox_remoteExtension->setChecked(isRemoteExtension);

    ui->lineEdit_snapDistance->setText(QString::number(distanceSnapSize));

    ui->checkBox_Length->setChecked(isSnapLength);
    ui->lineEdit_Length->setEnabled(isSnapLength);

    ui->checkBox_Degree->setChecked(isSnapAngle);
    ui->lineEdit_Degree->setEnabled(isSnapAngle);

    SetGlobalAngleAndLength();

    SetAllButtonStatus(isSnapEnabled);
}

SnapSetDialog::~SnapSetDialog()
{
}

void SnapSetDialog::OKButtonPushed()
{
    GetCheckBoxStatus();
}

void SnapSetDialog::CancelButtonPushed()
{
    QDialog::reject();
}

void SnapSetDialog::GetCheckBoxStatus()
{
    bool isSnapEnable          = (Qt::Checked != ui->checkBox_closesnap->checkState());
    bool isSnapToEndPoint      = (Qt::Checked == ui->checkBox_end->checkState());
    bool isSnapToMidPoint      = (Qt::Checked == ui->checkBox_centerpoint->checkState());
    bool isSnapToNearestPoint  = (Qt::Checked == ui->checkBox_online->checkState());
    bool isSnapToHVLine        = (Qt::Checked == ui->checkBox_horver->checkState());
    bool isSnapToPerpLine      = (Qt::Checked == ui->checkBox_perpecular->checkState());
    bool isSnapToIntersect     = (Qt::Checked == ui->checkBox_intersectpoint->checkState());
    bool isSnapQuadrant        = (Qt::Checked == ui->checkBox_quadrant->checkState());

    bool isSnapCenter = (Qt::Checked == ui->checkBox_center->checkState());
    bool isSnapTangent = (Qt::Checked == ui->checkBox_tange->checkState());

    // 远程捕捉
    bool isRemoteParallel = (Qt::Checked == ui->checkBox_remoteParallel->checkState());
    bool isRemotePerpendicular = (Qt::Checked == ui->checkBox_remotePerpendicular->checkState());
    bool isRemoteExtension = (Qt::Checked == ui->checkBox_remoteExtension->checkState());

    bool isSnapLength =  (Qt::Checked == ui->checkBox_Length->checkState());
    bool isSnapAngle  =  (Qt::Checked == ui->checkBox_Degree->checkState());

    int distanceSnapSize = ui->lineEdit_snapDistance->text().toInt();

    //标注角度捕捉数据
    QString angleString    = ui->lineEdit_Degree->text();
    QStringList stringList = angleString.split(";");
    int numString = stringList.size();

    std::vector<double> angleValueList;
    for (int i = 0 ; i < numString; i++)
    {
        QString curValue = stringList.at(i);
        bool isOk = false;
        double value = curValue.toDouble(&isOk);
        if (!isOk)
        {
            UiCommonDialog::ShowMessageBox(GBMP_TR(L"错误"), GBMP_TR(L"角度增量捕捉非法输入"), (int)UiCommonDialog::ButtonType::OK);
            return;
        }
        angleValueList.insert(angleValueList.end(), value);
    }
    std::sort(angleValueList.begin(),angleValueList.end(),std::greater<double>()); 

    //标注长度捕捉数据
    QString lengthString    = ui->lineEdit_Length->text();
    QStringList legnthStringList = lengthString.split(";");
    int numLengthString = legnthStringList.size();

    std::vector<double> lengthValueList;
    for (int i = 0 ; i < numLengthString; i++)
    {
        QString curValue = legnthStringList.at(i);
        bool isOk = false;
        double value = curValue.toDouble(&isOk);
        if (!isOk)
        {
            UiCommonDialog::ShowMessageBox(GBMP_TR(L"错误"), GBMP_TR(L"长度增量捕捉非法输入"), (int)UiCommonDialog::ButtonType::OK);
            return;
        }
        lengthValueList.insert(lengthValueList.end(), value);
    }

    std::sort(lengthValueList.begin(),lengthValueList.end(), std::greater<double>()); 

    ISnapSettings* curSet = ISnapSettings::GetGlobalSnapSettings();
    curSet->SetIsSnapOff(!isSnapEnable);
    curSet->SetSnapDistance(distanceSnapSize);
    curSet->SetCanSnapCenter(isSnapCenter);
    curSet->SetCanSnapEndPoint(isSnapToEndPoint);
    curSet->SetCanSnapIntersectionPoint(isSnapToIntersect);
    curSet->SetCanSnapMiddlePoint(isSnapToMidPoint);
    curSet->SetCanSnapNearest(isSnapToNearestPoint);
    curSet->SetCanSnapPerpendicularPoint(isSnapToPerpLine);
    curSet->SetCanSnapTangent(isSnapTangent);
    curSet->SetCanSnapHorizontalVerticalLine(isSnapToHVLine);
    curSet->SetCanSnapQuadrants(isSnapQuadrant);  

    curSet->SetCanParallelSnap(isRemoteParallel);
    curSet->SetCanPerpendicularSnap(isRemotePerpendicular);
    curSet->SetCanExtensionSnap(isRemoteExtension);

    curSet->SetSnapAngles(angleValueList);
    curSet->SetSnapLengths(lengthValueList);

    curSet->SetCanSnapAngle(isSnapAngle);
    curSet->SetCanSnapLength(isSnapLength);

   QDialog::accept();
}

void SnapSetDialog::onMoveRequested(const QPoint& cursorPos, const QPoint& offset)
{
    Q_UNUSED(cursorPos);
    move(pos() + offset);
}
